/*
 * Copyright 2006 POB-Technology. All rights reserved.
 * POB-Technology PROPRIETARY/CONFIDENTIAL.
 * 
 */

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace RgbComponent
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm
	{
		[STAThread]
		public static void Main(string[] args)
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			Application.Run(new MainForm());
		}
		
		static int W = 88 ; //width of pob-eye frame
		static int H = 120; //height of pob-eye frame 
		
		
		Communication communication ;
		
		string []serialPort ; //com port on your computer
		bool connected ;  //true if pob-eye is connected
		
		byte []buffer ;   //communication buffer 
		
		Ip ip ;          //internet communication object
		Serial serial ;  //serial communication object
		
		//byte buffer of rgb component
		byte []red ;
		byte []green ;
		byte []blue ; 
		
		//bitmap of rgb component
		Bitmap redBmp , greenBmp, blueBmp, rgbBmp ;
		
		bool FollowCross;
		
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			//
			// TODO: Add constructor code after the InitializeComponent() call.
			//
		
			buffer = new byte[3] ;
			
			buttonIpConnect.Click += new System.EventHandler(this.BConnectClick);
			groupBoxIp.Visible = false ;
			groupBoxIp.Enabled = false ;
			groupBoxIp.Location = groupBoxSelect.Location ;
			
			serialToolStripMenuItem.Checked = true ;
			
			serialPort = Serial.GetPortNames();
			comboBoxPortCom.Items.AddRange(serialPort);
			
			comboBoxBaud.Items.AddRange( new string[]{"230400","115200","57600","38400","19200","9600","4800","2400"} );
			comboBoxBaud.SelectedIndex = 1 ;
			
			connected = false ;
			groupBoxRgb.Enabled = false ;
			
			FollowCross = false;
			
			bSaveRaw.Enabled = false ;
			bSaveBmp.Enabled = false ;
			
			comboComponent.Items.Add("RGB");
			comboComponent.Items.Add("HSL");
			comboComponent.Items.Add("YUV");
			comboComponent.SelectedIndex=0;
			
			numericRc0.Name = "0" ;
			numericRc1.Name = "1" ;
			numericRc2.Name = "2" ;
			numericRc3.Name = "3" ;
			numericRc6.Name = "6" ;
			numericRc7.Name = "7" ;
			
			numericRc0.ValueChanged += new System.EventHandler(this.NumericValueChanged);
			numericRc1.ValueChanged += new System.EventHandler(this.NumericValueChanged);
			numericRc2.ValueChanged += new System.EventHandler(this.NumericValueChanged);
			numericRc3.ValueChanged += new System.EventHandler(this.NumericValueChanged);
			numericRc6.ValueChanged += new System.EventHandler(this.NumericValueChanged);
			numericRc7.ValueChanged += new System.EventHandler(this.NumericValueChanged);
			
			groupBoxServo.Enabled = false ;
			
			labelCon.Enabled = false ;
			labelBri.Enabled = false ;
			labelSat.Enabled = false ;
				
			numericCon.Enabled = false;
			numericCon.Text = "72";
			numericBri.Enabled = false ;
			numericBri.Text = "128" ;
			numericSat.Enabled = false;
			numericSat.Text = "128" ;
			
			lClickXY.Text = "" ;
			lClickRGB.Text = "" ;
			lClickHSL.Text = "" ;
		}
		
		//select communication type
		void CommunicationSelectToolStripMenuItemClick(object sender, System.EventArgs e)
		{
			if( sender == serialToolStripMenuItem )
			{
				if( iPToolStripMenuItem.Checked == true && communication != null )
					communication.Close();
				
				groupBoxSelect.Visible = true;
				groupBoxSelect.Visible = true;
				
				groupBoxIp.Visible = false;
				groupBoxIp.Enabled = false;
				
				serialToolStripMenuItem.Checked = true ;
				iPToolStripMenuItem.Checked = false ;
			}
			else
			{
				if( serialToolStripMenuItem.Checked == true && communication != null  )
					communication.Close();
				
				groupBoxSelect.Visible = false;
				groupBoxSelect.Visible = false;
				
				groupBoxIp.Visible = true;
				groupBoxIp.Enabled = true;
				
				serialToolStripMenuItem.Checked = false ;
				iPToolStripMenuItem.Checked = true ;
			}
		}
		
		//connect button event click
		void BConnectClick(object sender, System.EventArgs e)
		{
			if( serialToolStripMenuItem.Checked == true && comboBoxPortCom.SelectedIndex == -1 )
				return ;
			
			if( connected == false )
			{
				if( serialToolStripMenuItem.Checked == true )
				{
					//get serial port
					string portcom = serialPort[comboBoxPortCom.SelectedIndex];
					string baud = (string)comboBoxBaud.Items[comboBoxBaud.SelectedIndex];
					
					serial = new Serial( portcom,int.Parse(baud),8);
					communication = serial ;
				}
				else
				{
					//get ip address
					string ipAddress = ipBox.Text ;
					
					ip = new Ip(ipAddress,10002);
					communication = ip ;
				}
				
				try {
					communication.Open();
					
					buffer[0] = (byte)'P';
					buffer[1] = (byte)'O';
					buffer[2] = (byte)'B';
				
					communication.Write(buffer,3);
					communication.Read(buffer,3);
					
				} catch(Exception ex)
				{
					communication.Close();
					MessageBox.Show( "Reset your pob-eye, verify serial commnuation or set pob-eye in correct mode  \n\n" 
					                +ex.ToString(),"Failed to connect to POB-EYE", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return ;
				}
				
				if(  serialToolStripMenuItem.Checked )
					bConnect.Text = "Disconnect";
				else
					buttonIpConnect.Text = "Disconnect";
				
				connected = true ;
				groupBoxRgb.Enabled = true ;
				groupBoxServo.Enabled = true ;
			}
			else
			{
				communication.Close();
				
				if(  serialToolStripMenuItem.Checked )
					bConnect.Text = "Connect" ;
				else
					buttonIpConnect.Text = "Connect" ;
				
				connected = false ;
				groupBoxRgb.Enabled = false ;
				groupBoxServo.Enabled = false ;
			}
		}
		
		//get a new frame 
		void GetNewFrame()
		{
			buffer[0] = (byte)'R' ;
			buffer[1] = (byte)'G' ;
			buffer[2] = (byte)'B' ;
			
			communication.Write(buffer,3);
		}
		
		void GetNewHslFrame()
		{
			buffer[0] = (byte)'H' ;
			buffer[1] = (byte)'S'; 
			buffer[2] = (byte)'L' ;
			
			communication.Write(buffer,3);
		}
		
		void SetCompressionMode(bool on)
		{
			buffer[0] = (byte)'Z';
			buffer[1] = (byte)'I';
			if( on==true)
				buffer[2] = (byte)'1';
			else
				buffer[2] = (byte)'0';
			
			communication.Write(buffer,3);
		}
		
		//Get a color component from pob-eye
		byte []GetComponent( string command )
		{
			byte [] component = new byte[W*H] ;
			int inc=1 ;
			
			buffer[0] = (byte)command[0] ;
			buffer[1] = (byte)command[1] ; buffer[2] = (byte)command[2] ;
			
			bRefresh.Enabled = false ;
			groupBoxSelect.Enabled = false;
			groupBoxRgb.Enabled = false ;
			groupBoxServo.Enabled = false ;
			
			if( checkCompress.Checked==true)
				inc=2;
			else
				inc=1;
			
			try {
				communication.Write(buffer,3);
				
				for(int i=0 ; i < component.Length ; i=i+inc )
				{
					communication.Read(buffer,1);
					
					if( checkCompress.Checked==true)
					{
						component[i]=(byte)((int)buffer[0] & (int)0xF0) ;
						component[i+1]= (byte)((int)(buffer[0]&(int)0x0F) << 4 );
					}
					else
					{
						component[i] = buffer[0];
					}
					
					//component[i] = (byte)((int)buffer[0] & (int)0xF0) ; //2006.11.30
					
					//to prevent pob-eye serial crash, send one byte to clear pob-eye serial buffer
					if( i%500==0)
						communication.Write(buffer,1);
					
					progressRgb.Value=progressRgb.Value+inc ;
				}
			} catch(Exception e)
			{
				MessageBox.Show( "Reset our pob-eye or verify serial communication \n\n" 
				                + e.ToString(),"Serial communication error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			
			progressRgb.Value = 0 ;
			
			bRefresh.Enabled = true ;
			groupBoxRgb.Enabled = true ;
			groupBoxSelect.Enabled = true;
			groupBoxServo.Enabled = true ;
			
			return component ;
		}
		
		//draw component in picture object
		Bitmap DrawComponent( PictureBox img , byte []component)
		{
			Bitmap bmp = new Bitmap(W,H);
			Color c = new Color();
			
			int color1=0,color2=0,color3=0 ;
			
			for(int i=0 ; i < W ; i++ )
			{
				for(int j=0 ; j < H ; j++ )
				{
					color1 = component[i+j*W];
					color2 = color1;
					color3 = color1;
					
					if ( img == Red ){
						c = Color.FromArgb(color1,color2,color3);
					}
					else if( img == Green ) {
						c = Color.FromArgb(color2,color1,color3);
					}
					else if( img == Blue ){
						c = Color.FromArgb(color2,color3,color1);
					}
					
					bmp.SetPixel(i,j, c); //very slow : (
				}
			}
			
			img.Image = bmp ;
			img.Invalidate();
		
			return bmp ;
		}
		
		//draw rgb in picture object
		Bitmap DrawComponent( PictureBox img , byte []r,byte []g,byte []b)
		{
			Bitmap bmp = new Bitmap(W,H);
			Color c = new Color();
			
			int color1=0,color2=0,color3=0 ;
			
			for(int i=0 ; i < W ; i++ )
			{
				for(int j=0 ; j < H ; j++ )
				{
					color1 = r[i+j*W] ;
					color2 = g[i+j*W] ;
					color3 = b[i+j*W] ;
					
					c = Color.FromArgb(color1,color2,color3);
					
					bmp.SetPixel(i,j, c);
				}
			}
			
			img.Image = bmp ;
			img.Invalidate();
			
			return bmp ;
		}
		
		void ComboComponentSelectedIndexChanged(object sender, System.EventArgs e)
		{
			if( comboComponent.SelectedIndex == 0 )
			{
				labelRed.Text = "Red" ;
				labelGreen.Text = "Green";
				labelBlue.Text = "Blue";
				labelRGB.Text = "RGB - Clik on the picture to get RGB and HSL value";
			}
			else if( comboComponent.SelectedIndex == 1 )
			{
				labelRed.Text = "Hue" ;
				labelGreen.Text = "Saturation";
				labelBlue.Text = "Light";
				labelRGB.Text = "";
				
				lClickXY.Text = "" ; lClickRGB.Text = "" ; lClickHSL.Text = "" ;
			}
			else if( comboComponent.SelectedIndex == 2 )
			{
				labelRed.Text = "Y" ;
				labelGreen.Text = "U";
				labelBlue.Text = "V";
				labelRGB.Text = "RGB";
				
				lClickXY.Text = "" ; lClickRGB.Text = "" ; lClickHSL.Text = "" ;
			}
		}
		
		//refresh button event click
		void BRefreshClick(object sender, System.EventArgs e)
		{	
			if( checkCamera.Checked == true )
			{
				SendParameterToCamera();
			}
			
			if( checkCompress.Checked == true )
			{
				SetCompressionMode(true);
			}
			else
			{
				SetCompressionMode(false);
			}
			
			if( comboComponent.SelectedIndex == 0 )
			{
				GetNewFrame();
			
				red = GetComponent("RED");
				green = GetComponent("GRE");
				blue = GetComponent("BLU");

				redBmp = DrawComponent( Red, red );
				greenBmp = DrawComponent( Green, green);
				blueBmp = DrawComponent( Blue, blue);
				rgbBmp = DrawComponent( Rgb, red,green,blue);
				
				
				bSaveRaw.Enabled = true ;
				bSaveBmp.Enabled = true ;
			}
			else if( comboComponent.SelectedIndex == 1 )
			{
				GetNewHslFrame();
				
				red = GetComponent("HUE"); //get hue
				green = GetComponent("SAT"); //get saturation
				blue = GetComponent("LIG"); //get light
				
				Rgb.Image = null ;
				Red.Invalidate();
				
				redBmp = DrawComponent( Red, red);
				greenBmp = DrawComponent( Green, green);
				blueBmp = DrawComponent( Blue, blue);
				
				//rgbBmp = DrawComponent( Rgb, red,green,blue);
				
				bSaveRaw.Enabled = true ;
				bSaveBmp.Enabled = true ;
			}
			else if( comboComponent.SelectedIndex == 2 )
			{
				GetNewFrame();
			
				red = GetComponent("RED");
				green = GetComponent("GRE");
				blue = GetComponent("BLU");
				
				byte []y = new byte[H*W];
				byte []u = new byte[H*W];
				byte []v = new byte[H*W];
				
				for(int i=0 ; i < H*W; i++ )
				{
					//formula from ov6620 spec
					y[i] = (byte)((float)0.59 * green[i] + (float)0.31 * red[i] + (float)0.11 * blue[i] );
					u[i] = (byte)(red[i] - y[i]) ;
					if( u[i] < 0 )
						u[i] += 127;
					v[i] = (byte)(blue[i] - y[i]) ;
					if( v[i] < 0 )
						v[i] += 127;
				}
				
				redBmp = DrawComponent( Red, y );
				greenBmp = DrawComponent( Green, u);
				blueBmp = DrawComponent( Blue, v);
				//Rgb.Image = null ; Rgb.Invalidate();
				rgbBmp = DrawComponent( Rgb, y,u,v);
				
				//for save in raw format, set correct object
				red = y ;
				green = u ;
				blue = v ;
				
				bSaveRaw.Enabled = true ;
				bSaveBmp.Enabled = true ;
			}
			
		}
		
		//save bmp button click event
		void BSaveBmpClick(object sender, System.EventArgs e)
		{
			saveRgb.Title      = "Save "+ comboComponent.Items[comboComponent.SelectedIndex] +" in bitmap file" ;
			saveRgb.DefaultExt = "bmp" ;
			saveRgb.Filter     = "bitmap file (*.bmp)|*.bmp| All files (*.*)|*.*" ;
			saveRgb.FilterIndex = 1 ;
			saveRgb.FileName    = "" ;
			
			string redExt ="" ;
			string greenExt = "";
			string blueExt = "";
			
			if( comboComponent.SelectedIndex == 0 )
			{
				redExt = ".red.bmp" ;
				greenExt = ".green.bmp" ;
				blueExt = ".blue.bmp" ;
			}
			else if(comboComponent.SelectedIndex == 1 )
			{
				redExt = ".hue.bmp" ;
				greenExt = ".saturation.bmp" ;
				blueExt = ".light.bmp" ;
			}
			else if( comboComponent.SelectedIndex == 2 )
			{
				redExt = ".y.bmp" ;
				greenExt = ".u.bmp" ;
				blueExt = ".v.bmp" ;
			}
			
			if( saveRgb.ShowDialog() == DialogResult.OK ) {
				
				string filename = System.IO.Path.GetFileNameWithoutExtension(saveRgb.FileName);
				string path = System.IO.Path.GetDirectoryName(saveRgb.FileName);
				
				Image saveImg ;
				
				if( comboComponent.SelectedIndex == 0 || comboComponent.SelectedIndex == 2 )
				{
					saveImg = redBmp ;
					saveImg.Save( path + "\\" + filename + redExt );
					
					saveImg = rgbBmp ;
					saveImg.Save( saveRgb.FileName );
				}
				else if( comboComponent.SelectedIndex == 1 )
				{
					saveImg = redBmp ;
					saveImg.Save( path + "\\" + filename + redExt );
				}
				
				saveImg = greenBmp ;
				saveImg.Save( path + "\\" + filename + greenExt );
				
				saveImg = blueBmp ;
				saveImg.Save( path + "\\" + filename + blueExt );
			}
		}
		
		//save raw button click event
		void BSaveRawClick(object sender, System.EventArgs e)
		{
			saveRgb.Title      = "Save "+ comboComponent.Items[comboComponent.SelectedIndex] +" in binary form" ;
			saveRgb.DefaultExt = "bmp" ;
			saveRgb.Filter     = "bin file (*.bin)|*.bin| All files (*.*)|*.*" ;
			saveRgb.FilterIndex = 1 ;
			saveRgb.FileName    = "" ;
			
			string redExt ="" ;
			string greenExt = "";
			string blueExt = "";
			
			if( comboComponent.SelectedIndex == 0 )
			{
				redExt = ".red.bin" ;
				greenExt = ".green.bin" ;
				blueExt = ".blue.bin" ;
			}
			else if(comboComponent.SelectedIndex == 1 )
			{
				redExt = ".hue.bin" ;
				greenExt = ".saturation.bin" ;
				blueExt = ".light.bin" ;
			}
			else if(comboComponent.SelectedIndex == 2 )
			{
				redExt = ".y.bin" ;
				greenExt = ".u.bin" ;
				blueExt = ".v.bin" ;
			}
			
			if( saveRgb.ShowDialog() == DialogResult.OK ) {
				
				string filename = System.IO.Path.GetFileNameWithoutExtension(saveRgb.FileName);
				string path = System.IO.Path.GetDirectoryName(saveRgb.FileName);
				
				byte []rgb = new byte[W*H*3];
				
				for(int i=0,j=0 ; i < red.Length ; i++ , j += 3 )
				{
					rgb[j] = red[i] ;
					rgb[j+1] = green[i] ;
					rgb[j+2] = blue[i] ;
				}
				
				WriteFile( saveRgb.FileName, rgb );
				
				WriteFile( path + "\\" + filename + redExt, red );
				WriteFile( path + "\\" + filename + greenExt, green );
				WriteFile( path + "\\" + filename + blueExt, blue );
			}
				
		}
		
		static void WriteFile(string name, byte []buff )
		{
			System.IO.FileStream fs = null ;
			
			try {
				fs = System.IO.File.Open(name,System.IO.FileMode.Create);
				fs.Write(buff,0,buff.Length);
			}
			catch(Exception e)
			{
				throw e;
			}
			finally
			{
				if( fs != null )
					fs.Close();
			}
		}
		
		//numeric value changed event
		void NumericValueChanged( object sender, EventArgs e)
		{
			NumericUpDown obj = (NumericUpDown)sender ;
			
			int servomotor = int.Parse(obj.Name) ;
			int position = int.Parse(obj.Text);
			
			try {
				buffer[0] = (byte)'S'; buffer[1] = (byte)'E'; buffer[2] = (byte)'R' ;
				communication.Write(buffer,3);
				communication.Read(buffer,2);
				
				//send servo movement
				buffer[0] = (byte)'V' ;
				buffer[1] = (byte)servomotor ;
				buffer[2] = (byte)position ;
			
				communication.Write(buffer,3);
				communication.Read(buffer,2);
			} catch(Exception)
			{
				MessageBox.Show( "Do you have a pob-bot ? Verify pob-proto board or serial communication.\n\n" ,
				                "Error on POB-BOT", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			
			
		}
		
		void BTankClick(object sender, System.EventArgs e)
		{
			
			//send tank movement
			
			if( sender == bUp )
			{
				buffer[0] = (byte)'U' ;
				buffer[1] = (byte)'P' ;
			}
			else if( sender == bDown )
			{
				buffer[0] = (byte)'D' ;
				buffer[1] = (byte)'O' ;
			}
			else if( sender == bLeft )
			{
				buffer[0] = (byte)'L' ;
				buffer[1] = (byte)'E' ;
			}
			else if( sender == bRight )
			{
				buffer[0] = (byte)'R' ;
				buffer[1] = (byte)'I' ;
			}
			        
			buffer[2] = 0 ;
			
			try {
				communication.Write(buffer,3);
				communication.Read(buffer,2);
				
				Console.WriteLine("buffer movement:" + (char)buffer[0] + (char)buffer[1] );
				
			} catch(Exception)
			{
				MessageBox.Show( "Do you have a pob-bot ? Verify pob-proto board or serial communication.\n\n" ,
				                "Error on POB-BOT", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			
		}
		
		void ButtonCrossClick(object sender, System.EventArgs e)
		{
			if(FollowCross==false)
			{
				buffer[0]= (byte)'C';
				buffer[1]= (byte)'R';
				buffer[2]= (byte)'O';
				
				try{
					communication.Write(buffer,3);
					
					groupBoxBot.Enabled=false;
					groupBoxRgb.Enabled=false;
					numericRc0.Enabled=false;
					numericRc1.Enabled=false;
					numericRc2.Enabled=false;
					numericRc3.Enabled=false;
					numericRc6.Enabled=false;
					numericRc7.Enabled=false;
					FollowCross=true;
				} catch(Exception)
				{
					MessageBox.Show( "Do you have a pob-bot ? Verify pob-proto board or serial communication.\n\n" ,
				                "Error on POB-BOT", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
				
			}
			else
			{
				buffer[0]= (byte)'C';
				
				try{
					communication.Write(buffer,1);					
				} catch(Exception)
				{
					MessageBox.Show( "Do you have a pob-bot ? Verify pob-proto board or serial communication.\n\n" ,
				                "Error on POB-BOT", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
				groupBoxRgb.Enabled=true;
				groupBoxBot.Enabled=true;
				numericRc0.Enabled=true;
				numericRc1.Enabled=true;
				numericRc2.Enabled=true;
				numericRc3.Enabled=true;
				numericRc6.Enabled=true;
				numericRc7.Enabled=true;
				FollowCross=false;
			}
		}
		
		void SendParameterToCamera()
		{
			
			//send CAM
			buffer[0] = (byte)'C' ; buffer[1] = (byte)'A' ; buffer[2] = (byte)'M' ;
			communication.Write(buffer,3);
			communication.Read(buffer,2);
			
			//send saturation
			buffer[0] = (byte)'S' ; buffer[1] = (byte)'A' ; 
			buffer[2] = byte.Parse(numericSat.Text);
			communication.Write(buffer,3);
			
			//send contrast
			buffer[0] = (byte)'C' ; buffer[1] = (byte)'A' ; buffer[2] = (byte)'M' ;
			communication.Write(buffer,3);
			communication.Read(buffer,2);
			
			buffer[0] = (byte)'C' ; buffer[1] = (byte)'O' ; 
			buffer[2] = byte.Parse(numericCon.Text);
			communication.Write(buffer,3);
			
			//send brightness
			buffer[0] = (byte)'C' ; buffer[1] = (byte)'A' ; buffer[2] = (byte)'M' ;
			communication.Write(buffer,3);
			communication.Read(buffer,2);
			
			buffer[0] = (byte)'B' ; buffer[1] = (byte)'R' ; 
			buffer[2] = byte.Parse(numericBri.Text);
			communication.Write(buffer,3);
			
			
		}
		
		void CheckCameraCheckedChanged(object sender, System.EventArgs e)
		{
			if( checkCamera.Checked == true )
			{
				labelCon.Enabled = true ;
				labelBri.Enabled = true ;
				labelSat.Enabled = true ;
				
				numericCon.Enabled = true;
				numericBri.Enabled = true ;
				numericSat.Enabled = true ;
			}
			else
			{
				labelCon.Enabled = false ;
				labelBri.Enabled = false ;
				labelSat.Enabled = false ;
				
				numericCon.Enabled = false;
				numericBri.Enabled = false ;
				numericSat.Enabled = false;
			}
			
		}
		
		//rgb picture click event
		void RgbClick(object sender, System.EventArgs e)
		{
			MouseEventArgs mouseEvent = (MouseEventArgs) e ;
			
			byte hue, saturation, light ;
			
			if( comboComponent.SelectedIndex == 0 && Rgb.Image != null )
			{
				//get rgb value and transform to HSL value
				Rgb2Hsl( red[mouseEvent.X + mouseEvent.Y * W ],
				         green[mouseEvent.X + mouseEvent.Y * W ],
				         blue[mouseEvent.X + mouseEvent.Y * W ],
				         out hue, out saturation, out light );
				
				//display HSL value
				lClickXY.Text = "X=" + mouseEvent.X + " Y="+ mouseEvent.Y  ;
				lClickRGB.Text = "RGB=" + red[mouseEvent.X + mouseEvent.Y * W ] + "," +
								green[mouseEvent.X + mouseEvent.Y * W ] + "," +
								blue[mouseEvent.X + mouseEvent.Y * W ] ;
				
				lClickHSL.Text = "HSL=" + hue + "," + saturation + "," + light ;
			}
		}
		
		
		void Rgb2Hsl(byte r, byte g, byte b, out byte hue, out byte saturation,out byte light)
		{
			float T0 = 255;
	
			float TMax = 240 ;
			float SMax = 240 ;
			float VMax = 255 ;
			float LMax = 240 ;
	
			float Delta ;

			float s,l ;

			int t ;
			float Min ; 
			float Max ; 
	
			Min = (float)r;
			Max = (float)r ;
	
			if( g > Max ) Max=(float)g;
			if( g < Min ) Min=(float)g;
			if( b > Max ) Max=(float)b;
			if( b < Min ) Min=(float)b;
		
			Delta = Max - Min;
	
			if( r == Max )
			{
				T0 = ( g - b )/ Delta ; 
			}
			else if( g == Max)
			{
				T0 = ( b - r )/ Delta +2;
			}
			else if( b == Max)
			{
				T0 = ( r - g )/ Delta +4;
			}
			
			t = (int)((float)((T0*TMax)/6)) % 240 /*TMax*/ ;
			
			//saturation
			s=0 ;
			if( Max + Min <= VMax )
			{
				s = (float)(SMax * ( Delta / ( Max + Min ) ) );
			}
			else if( Max + Min >= VMax )
			{
				s = (float)(SMax *( Delta / ( 2*VMax - (Max+Min) ) ));
			}
	
			//light
			l = (int)(float)(LMax * ( Max + Min ) / ( 2*VMax) );
	 
			//verify rgb
			if( r==g && r==b && g==b )
				s = 0 ;
			
			if( r==0 && g==0 && b==0 )
				l = 0 ;
	
			if( r==VMax && g==VMax && b==VMax )
				l = LMax ;
	
	
			hue = (byte)t ;
			saturation = (byte)(int)s ;
			light = (byte)(int)l ;
	

		  	
		  	//Console.WriteLine(" rgb=("+ r+","+g+","+b+") hsl="+t+","+s+","+l);
		  	
		}
		
	}
}
